int nr = smp_processor_id();
struct tss_struct *t = &init_tss[nr];
- if ( !VALID_DATASEL(ss) )
- return -EINVAL;
-
+ /*
+ * No need to check validity: CPU will fault if SS or ESP is bad. This is
+ * true even for a fast trap: a bad SS:ESP will get us either a #SS or #TS.
+ */
current->thread.ss1 = ss;
current->thread.esp1 = esp;
t->ss1 = ss;
&next_p->shared_info->execution_context,
sizeof(*stack_ec));
+ /*
+ * This is sufficient! If the descriptor DPL differs from CS RPL
+ * then we'll #GP. If DS, ES, FS, GS are DPL 0 then they'll be
+ * cleared automatically. If SS RPL or DPL differs from CS RPL
+ * then we'll #GP.
+ */
+ if ( (stack_ec->cs & 3) == 0 )
+ stack_ec->cs = 0;
+
unlazy_fpu(prev_p);
/* Switch the fast-trap handler. */
case PGT_l2_page_table:
err = mod_l2_entry((l2_pgentry_t *)req.ptr,
mk_l2_pgentry(req.val));
- break;
- default:
+ break;
+ case PGT_none:
MEM_LOG("Update to non-pt page %08lx", req.ptr);
*(unsigned long *)req.ptr = req.val;
err = 0;
break;
+ default:
+ MEM_LOG("Update to bad page %08lx", req.ptr);
+ break;
}
}
else
#define load_TR(n) __asm__ __volatile__ ("ltr %%ax" : : "a" (__TSS(n)<<3) )
/*
- * Guest OS must provide its own code selectors, or use the one we provide.
- * The RPL must be 1, as we only create bounce frames to ring 1.
- * Any LDT selector value is okay.
+ * Guest OS must provide its own code selectors, or use the one we provide. The
+ * RPL must be 1, as we only create bounce frames to ring 1. Any LDT selector
+ * value is okay. Note that checking only the RPL is insufficient: if the
+ * selector is poked into an interrupt, trap or call gate then the RPL is
+ * ignored when the gate is accessed.
*/
-
#define VALID_SEL(_s) \
(((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) || \
(((_s)>>3) > LAST_RESERVED_GDT_ENTRY) || \
((_s)&4)) && \
(((_s)&3) == 1))
-
#define VALID_CODESEL(_s) ((_s) == FLAT_RING1_CS || VALID_SEL(_s))
-#define VALID_DATASEL(_s) ((_s) == FLAT_RING1_DS || VALID_SEL(_s))
-
/* These are bitmasks for the first 32 bits of a descriptor table entry. */
#define _SEGMENT_TYPE (15<< 8)
#define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */